package wangxiaotao.controller;

import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import wangxiaotao.aop.annotation.Log;
import wangxiaotao.bean.vo.AccountVO;
import wangxiaotao.bean.vo.ShowVO;
import wangxiaotao.common.CommonResult;
import wangxiaotao.converter.ShowConverter;
import wangxiaotao.converter.UserConverter;
import wangxiaotao.entity.User;
import wangxiaotao.entity.UserRoleRel;
import wangxiaotao.service.CommonService;
import wangxiaotao.service.impl.CommonServiceImpl;
import wangxiaotao.shiro.exception.PermissionException;
import wangxiaotao.tools.ConstValue;
import wangxiaotao.utils.JWTUtils;
import wangxiaotao.utils.RedisUtils;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 可以公共访问的接口
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/common")
public class CommonController extends BaseController{
    private final CommonService commonService;
    private final ShowConverter showConverter;
    private final UserConverter userConverter;
    private final ConstValue constValue;

    /**
     * 注册
     * @return
     */
    @PostMapping("/register")
    @Log
    public CommonResult register(@RequestBody Map<String,Object>  regester){
        User user = userConverter.toUser(regester);
        //默认头像
        user.setAvatar(constValue.getAvatar());
        if (userService.save(user)){
            UserRoleRel userRoleRel = new UserRoleRel();
            userRoleRel.setUserId(user.getId()).setRoleId(constValue.getDefaultRoleId());
            //设置默认角色
            userRoleRelService.save(userRoleRel);
            return CommonResult.success();
        }
        return CommonResult.fail();
    }

    @GetMapping("/checkUsername")
    public CommonResult checkUsername(@RequestParam String username){
        Long count = userService.getObj(new QueryWrapper<User>().select("count(1)").eq("username", username), s -> (long) s);
        return count==0?CommonResult.success():CommonResult.fail(400,"用户名已经存在",null);
    }

    /**
     * 登录
     * @param accountVO
     * @return
     */
    @PostMapping("/login")
    @Log
    public CommonResult login(@Validated @RequestBody AccountVO accountVO, HttpServletResponse response){
        return commonService.login(request,response,accountVO);
    }

    @GetMapping("/logout")
    public void logout(){
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()){
            //清除token缓存
            String token = (String)subject.getPrincipal();
            Integer id = Integer.parseInt(JWTUtils.getClaimByName(token, "id"));
            String tokenKeyPrefix = CommonServiceImpl.getTokenKeyPrefix(id);
            RedisUtils.remove(tokenKeyPrefix);
            subject.logout();
        }

    }

    /**
     * 获取所有banner 和notice 等
     * @return
     */
    @GetMapping("/getCommonShow")
    public CommonResult getCommonShow(){
        List<ShowVO> showVOList = showConverter.toShowVOList(showService.list());
        return CommonResult.success(showVOList);
    }

    /**
     * 获取前台显示的房间信息
     * @return
     */
    @GetMapping("/getAllSimpleRoomType")
    public CommonResult getAllRoomType(){
        return CommonResult.success(roomTypeService.queryAllRoomTypeForShow());
    }

    /**
     * 获取验证码图片 base64格式
     * @throws Exception
     */
    @GetMapping("/captcha")
    public CommonResult getCaptcha(){
        String key = UUID.randomUUID().toString();
        CircleCaptcha captcha = commonService.getCaptcha();
        //验证码存入redis
        RedisUtils.set(getCaptchaKey(key),captcha.getCode(),60);
        Map<String, Object> res = new HashMap<>();
        res.put("captcha",captcha.getImageBase64Data());
        res.put("key",key);
        return CommonResult.success(res);
    }

    /**
     * 检查验证码的正确
     * @param code
     * @return
     */
    @GetMapping("/checkCaptcha")
    @Log
    public CommonResult checkCaptcha(@NotBlank(message = "验证码不能为空") String code,@NotBlank(message = "校验失败") String key){
        Object o = RedisUtils.get(getCaptchaKey(key));
        //验证码读出
        if (!code.equals(o))
            return CommonResult.fail("验证码错误",null);
        return CommonResult.success();
    }

    /**
     * 异常转发
     * spring无法拦截shirofilter抛出的异常
     * shiro filter 是servlet filter 里面的实现
     */
    @RequestMapping("/exception")
    public void Exceptions(String e){
        throw new PermissionException(e);
    }

    private String getCaptchaKey(String captchaKey){
        return "captcha:cache:" + captchaKey;
    }
}
